package decomposition;

import matrix_operations.Matrix;

public abstract class Crout {
	
	private static String msg = "";

	public static Matrix[] factorizing(Matrix A) {
		
		msg = "";

		if (A.getN() != A.getM()) {
			msg = "Erro! The matrix can not be facored, because is not a square matrix.";
			System.out.println(msg);
			return null;
		}

		Matrix L = Matrix.getNullMatrix(A.getN(), A.getN());
		Matrix U = Matrix.getNullMatrix(A.getN(), A.getN());
		Matrix[] LU = new Matrix[2];

		double sum = 0;

		for (int i = 0; i < A.getN(); i++) {
			U.setValue(i, i, 1);
		}
		for (int j = 0; j < A.getN(); j++) {
			for (int i = j; i < A.getN(); i++) {
				sum = 0;
				for (int k = 0; k < j; k++) {
					sum += L.getValue(i, k) * U.getValue(k, j);
				}
				L.setValue(i, j, A.getValue(i, j) - sum);
			}

			for (int i = j; i < A.getN(); i++) {
				sum = 0;
				for (int k = 0; k < j; k++) {
					sum += L.getValue(j, k) * U.getValue(k, i);
				}
				if (L.getValue(j, j) == 0) {
					
					msg = "Erro! The Matrix cannot be factored with Crout's method";
					System.out.println(msg);
					return null;
				}
				U.setValue(j, i, (A.getValue(j, i) - sum) / L.getValue(j, j));
			}
		}

		LU[0] = L;
		LU[1] = U;
		return LU;
	}

	public static Matrix solveSysem(Matrix[] LU, Matrix B) {
		
		if (LU == null){
			msg = "Erro! The Matrix cannot be factored with Crout's method";
			return null;
		}		

		
		Matrix y = new Matrix(B.getN(), 1);
		Matrix x = new Matrix(B.getN(), 1);

		// Ly = B
		for (int i = 0; i < B.getN(); i++) {
			y.setValue(i, 0, (B.getValue(i, 0) - LU[0].getValue(i, i - 1)
					* y.getValue(i - 1, 0) / LU[0].getValue(i, i)));
		}

		// Ux = y
		for (int i = B.getN() - 1; i >= 0; i--) {
			x.setValue(i, 0, y.getValue(i, 0)
					- (LU[1].getValue(i, i + 1) * x.getValue(i + 1, 0)));
		}

		return x;
	}
	
	public static String getMsg(){
		return msg;
	}

}
